package com.yuliang.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuliang.constants.SystemConstants;
import com.yuliang.domain.R;
import com.yuliang.domain.dto.AddUserDto;
import com.yuliang.domain.entity.Role;
import com.yuliang.domain.entity.User;
import com.yuliang.domain.entity.UserRole;
import com.yuliang.domain.vo.*;
import com.yuliang.enums.AppHttpCodeEnum;
import com.yuliang.exception.SystemException;
import com.yuliang.mapper.UserMapper;
import com.yuliang.mapper.UserRoleMapper;
import com.yuliang.service.RoleService;
import com.yuliang.service.UserRoleService;
import com.yuliang.service.UserService;
import com.yuliang.utils.BeanCopyUtils;
import com.yuliang.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户表(User)表服务实现类
 *
 * @author makejava
 * @since 2023-09-20 11:04:54
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Override
    public R updateUserInfo(User user) {
        updateById(user);
        return R.okResult();
    }

    @Override
    public R addUser(AddUserDto addUserDto) {
        User user = BeanCopyUtils.copyBean(addUserDto, User.class);

        //用户名不能为空，否则提示：必需填写用户名
        if(!StringUtils.hasText(user.getUserName())){
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }
        //用户名必须之前未存在，否则提示：用户名已存在
        if (userNameExist(user.getUserName())){
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        //手机号必须之前未存在，否则提示：手机号已存在
        if (phoneNumExist(user.getPhonenumber())){
            throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
        }
        //邮箱必须之前未存在，否则提示：邮箱已存在
        if (emailExist(user.getEmail())){
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        //对密码进行加密
        String encode = passwordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        //存用户注册数据
        save(user);
        //关联user_role表
        List<Long> roleIds = addUserDto.getRoleIds();
        List<UserRole> list = new ArrayList<>();
        for (Long roleId:roleIds) {
            list.add(new UserRole(user.getId(),roleId));
        }
        userRoleService.saveBatch(list);
        return R.okResult();
    }

    @Override
    public R deleteUser(List<Long> ids) {
        //不能删除当前操作的用户
        for (Long id:ids) {
            if (id.equals(SecurityUtils.getUserId())){
                throw new SystemException(AppHttpCodeEnum.NOW_LOGIN);
            }
        }
        removeByIds(ids);
        return R.okResult();
    }


    @Override
    public R getUserDetail(Long id) {
        //响应格式：roleIds：用户所关联的角色id列表 | roles：所有角色的列表 | user：用户信息
        List<Long> roleIds = userRoleMapper.getRoleIdsByUserId(id);

        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getStatus, SystemConstants.STATUS_NORMAL);
        List<Role> roles = roleService.list(queryWrapper);

        User user = getById(id);
        UserPageVo userPageVo = BeanCopyUtils.copyBean(user, UserPageVo.class);
        return R.okResult(new UpdateUserVo(roleIds,roles,userPageVo));
    }

    @Override
    public R updateUser(AddUserDto addUserDto) {
        User user = BeanCopyUtils.copyBean(addUserDto, User.class);
        updateById(user);

        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId,user.getId());
        userRoleService.remove(queryWrapper);

        List<UserRole> list = new ArrayList<>();
        for (Long roleId:addUserDto.getRoleIds()) {
            list.add(new UserRole(user.getId(),roleId));
        }
        userRoleService.saveBatch(list);
        return R.okResult();
    }

    @Override
    public R register(User user) {
        //非空检验
        String userName = user.getUserName();
        String email = user.getEmail();
        String nickName = user.getNickName();
        String password = user.getPassword();

        if(!StringUtils.hasText(userName)){
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }
        if(!StringUtils.hasText(password)){
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }
        if(!StringUtils.hasText(email)){
            throw new SystemException(AppHttpCodeEnum.EMAIL_NOT_NULL);
        }
        if(!StringUtils.hasText(nickName)){
            throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
        }
        //信息重复
        if (userNameExist(userName)){
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        if (emailExist(email)){
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        if (nickNameExist(nickName)){
            throw new SystemException(AppHttpCodeEnum.NICKNAME_EXIST);
        }
        //对密码进行加密
        String encode = passwordEncoder.encode(password);
        user.setPassword(encode);
        //存用户注册数据
        save(user);
        return R.okResult();

    }

    private boolean emailExist(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail,email);
        return count(queryWrapper) > 0;
    }
    private boolean nickNameExist(String nickName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickName,nickName);
        return count(queryWrapper) > 0;
    }
    private boolean userNameExist(String userName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName,userName);
        return count(queryWrapper) > 0;
    }
    private boolean phoneNumExist(String phoneNum) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhonenumber,phoneNum);
        return count(queryWrapper) > 0;
    }

    @Override
    public R userInfo() {
        Long userId = SecurityUtils.getUserId();
        User user = getById(userId);
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        return R.okResult(userInfoVo);
    }

    @Override
    public R userPageList(Integer pageNum, Integer pageSize, String userName, String phonenumber, String status) {
        //分页
        IPage<User> page = new Page<>(pageNum,pageSize);
        //可以根据用户名模糊搜索。进行手机号的搜索。可以进行状态的查询。
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.hasText(userName),User::getUserName,userName);
        queryWrapper.eq(StringUtils.hasText(phonenumber),User::getPhonenumber,phonenumber);
        queryWrapper.eq(StringUtils.hasText(status),User::getStatus,status);

        page(page,queryWrapper);
        //To vo
        List<UserPageVo> userPageVos = BeanCopyUtils.copyBeanList(page.getRecords(), UserPageVo.class);
        return R.okResult(new PageVo(userPageVos,page.getTotal()));
    }
}
